<script setup lang="ts">
import '@wangeditor/editor/dist/css/style.css'
import {ref, shallowRef, onBeforeUnmount, nextTick} from 'vue';
import {Editor, Toolbar} from '@wangeditor/editor-for-vue'
import {IToolbarConfig, IEditorConfig, IDomEditor, SlateElement} from '@wangeditor/editor';
import {uploadFileHeader} from "@/util/Auth.ts";

const value = defineModel<string | null>('value', {type: String, default: ''});
const mode = defineModel<string>('mode', {type: String, default: 'default'}); //simple
const height = defineModel<string>('height', {type: String, default: '300px'});
const placeholder = defineModel<string>('placeholder', {type: String, default: '请输入内容...'});
const lang = defineModel<string>('lang', {type: String, default: 'zh'});
type ImageElement = SlateElement & {
  src: string
  alt: string
  url: string
  href: string,
  style: Object | any,
}
// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef<IDomEditor>()
const editorRefs = ref<HTMLElement | null>(null);
const editorConfig: Partial<IEditorConfig> = {
  placeholder: placeholder.value || undefined,

  MENU_CONF: {
    //字体列表
    fontFamily: {
      fontFamilyList: [
        // 元素支持两种形式
        //   1. 字符串；
        //   2. { name: 'xxx', value: 'xxx' }
        '黑体',
        '仿宋',
        '楷体',
        '标楷体',
        '华文仿宋',
        '华文楷体',
        '宋体',
        '微软雅黑',
        'Arial',
        'UKIJEkran'
      ]
    },
    //上传图片
    uploadImage: {
      server: '/api/sys/upload_img_editor',
      fieldName: 'file',
      // 单个文件的最大体积限制，默认为 2M
      maxFileSize: 3 * 1024 * 1024, // 1M
      // 选择文件时的类型限制，默认为 ['image/*'] 。如不想限制，则设置为 []
      allowedFileTypes: ['image/*'],
      metaWithUrl: false,
      // 自定义增加 http  header
      headers: uploadFileHeader(),
      // 超时时间，默认为 10 秒
      timeout: 5 * 1000, // 5 秒
    },
    //上传视频
    uploadVideo: {
      server: '/api/sys/upload_video_editor',
      fieldName: 'editor-video',
      // 单个文件的最大体积限制，默认为 10M
      maxFileSize: 500 * 1024 * 1024, // 5M
      // 最多可上传几个文件，默认为 5
      maxNumberOfFiles: 1,
      // 选择文件时的类型限制，默认为 ['video/*'] 。如不想限制，则设置为 []
      allowedFileTypes: ['video/*'],
      // 自定义增加 http  header
      headers: uploadFileHeader(),
      // 超时时间，默认为 30 秒
      timeout: 60 * 1000, // 60 秒
      // 上传进度的回调函数
      onProgress(progress: number) {  // TS 语法
        // onProgress(progress) {       // JS 语法
        // progress 是 0-100 的数字
        console.log('progress', progress)
      },
      // 单个文件上传成功之后
      onSuccess(file: File, res: any) {  // TS 语法
        // onSuccess(file, res) {          // JS 语法
        console.log(`${file.name} 上传成功`, res)
      },

      // 单个文件上传失败
      onFailed(_file: File, res: any) {  // TS 语法
        // const upload_data={errno:res.errno,data:{url:Config.VIEW_FILE +res.data.url,poster:Config.VIEW_FILE +res.data.poster}}
        // console.log(upload_data)
        console.log(res)
      },

      // 上传错误，或者触发 timeout 超时
      onError(file: File, err: any, res: any) {  // TS 语法
        // onError(file, err, res) {               // JS 语法
        console.log(`${file.name} 上传出错`, err, res)
      },
    },
    insertImage: {
      onInsertedImage(imageNode: ImageElement | null) {
        if (imageNode == null) return
        return `<img src="${imageNode.src}" alt="${imageNode.alt}" data-href="${imageNode.href}" style="${imageNode.style}"/>`
      },
    }
  }
}

// 工具栏配置
const toolbarConfig: Partial<IToolbarConfig> = {
  //禁用
  excludeKeys: [
    'fullScreen',
    'emotion',
    'todo',
  ]
}
//编辑器默认配置  如：默认字体 等等
const htmlContent = value.value ? value.value : lang.value == 'uy' ? '<p  style="text-align: right;"><span dir="auto" style="font-family: UKIJEkran;text-align: right;"></span></p>' : '<p><span></span></p>'
const handleCreated = (editor: any) => {
  editorRef.value = editor // 记录 editor 实例，重要！
  nextTick(() => {
    const editor = editorRef.value
  })
}
const handleChange = (_editor: any) => {
  const editor_box: HTMLElement | null = editorRefs.value && editorRefs.value['box'];
  if (editor_box && editor_box.classList.contains('uy_editor')) {
    const pElements = editor_box.querySelectorAll('[data-slate-node="element"][style*="text-align: right"]');
    pElements.forEach((pElement) => {
      const pHTMLElement = pElement as HTMLElement;
      pHTMLElement.style.direction = 'rtl'; // 为符合条件的p元素赋予rtl方向
    });
  }
}

// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
  const editor = editorRef.value
  if (editor == null) return
  editor.destroy()
})
</script>

<template>
  <div style="border:1px solid #ccc;">
    <toolbar
        style="border-bottom: 1px solid #ccc"
        :editor="editorRef"
        :defaultConfig="toolbarConfig"
        :mode="mode"
    ></toolbar>
    <editor
        :class="lang=='uy'?'uy_editor':''"
        ref="editorRefs"
        :style="{height:height,overflowY:'hidden'}"
        v-model="value"
        :defaultConfig="editorConfig"
        :defaultHtml="htmlContent"
        :mode="mode"
        @onCreated="handleCreated" @onChange="handleChange"/>
  </div>
</template>

<style scoped lang="scss">
:deep(.uy_editor .w-e-text-placeholder) {
  right: 10px !important;
  left: unset !important;
  font-family: UKIJEkran, serif;
  direction: rtl;
  text-align: right;
}
</style>

